package com.wechat.controller;

import com.wechat.annotation.GlobalInterceptor;
import com.wechat.entity.config.AppConfig;
import com.wechat.entity.constants.Constants;
import com.wechat.entity.dto.MessageSendDto;
import com.wechat.entity.dto.TokenUserInfoDto;
import com.wechat.entity.enums.MessageTypeEnum;
import com.wechat.entity.enums.ResponseCodeEnum;
import com.wechat.entity.po.ChatMessage;
import com.wechat.entity.vo.ResponseVO;
import com.wechat.exception.BusinessException;
import com.wechat.service.ChatMessageService;
import com.wechat.service.ChatSessionUserService;
import com.wechat.utils.StringTools;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.Max;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;

/*
 实现聊天功能
 */
@RestController
@RequestMapping("/chat")
@Slf4j
public class ChatController extends ABaseController{
    @Resource
    private ChatMessageService chatMessageService;

    @Resource
    private ChatSessionUserService chatSessionUserService;

    @Resource
    private AppConfig appConfig;

    /**
     * 发送消息
     * @param contactId
     * @param messageContent
     * @param messageType
     * @param fileSize
     * @param fileName
     * @param fileType
     * @return
     */
    @RequestMapping("/saveMessage")
    @GlobalInterceptor
    public ResponseVO sendMessage(HttpServletRequest request,
                                  @NotEmpty String contactId,
                                  @NotEmpty @Max(500) String messageContent,
                                  @NotEmpty Integer messageType,
                                  Long fileSize,
                                  String fileName,
                                  Integer fileType){
        TokenUserInfoDto tokenUserInfoDto = getTokenUserInfo(request);//获取用户信息

        ChatMessage chatMessage = new ChatMessage();//创建聊天消息对象
        chatMessage.setContactId(contactId);
        chatMessage.setMessageContent(messageContent);
        chatMessage.setFileSize(fileSize);
        chatMessage.setFileName(fileName);
        chatMessage.setFileType(fileType);
        chatMessage.setMessageType(messageType);

        MessageSendDto messageSendDto = chatMessageService.saveMessage(chatMessage, tokenUserInfoDto);//保存信息
        return getSuccessResponseVO(messageSendDto);


    }

    /**
     * 上传文件
     * @param messageId
     * @param file
     * @param cover
     * @return
     */
    @RequestMapping("/uploadFile")
    @GlobalInterceptor
    public ResponseVO uploadFile(HttpServletRequest request,
                                 @NotNull Long messageId,
                                 @NotNull MultipartFile file,
                                 @NotNull MultipartFile cover){
        TokenUserInfoDto tokenUserInfoDto = getTokenUserInfo(request);
        chatMessageService.uploadMessageFile(tokenUserInfoDto.getUserId(), messageId, file, cover);
        return getSuccessResponseVO(null);

    }

    /**
     * 下载文件
     * @param fileId---接收的文件Id
     *              非数字的fileId，则说明是头像
     *              纯数字的fileId，则说明是消息文件=messageId
     */
    @RequestMapping("/downloadFile")
    @GlobalInterceptor
    public void downloadFile(HttpServletRequest request,
                                   HttpServletResponse response,
                                   @NotEmpty String fileId,
                                   @NotNull Boolean showCover){
        TokenUserInfoDto tokenUserInfoDto = getTokenUserInfo(request);
        OutputStream outputStream = null;
        FileInputStream inputStream = null;
        try {
            File file = null;
            /*
             * 如果fileId不是数字，则说明是头像(头像图/封面图)--因为命名是以U开头
             * 如果是纯数字id，则说明是消息文件，因为存储的时候，消息id和文件id是相同的
             */
            if(!StringTools.isNumber(fileId)){
                String avatarFolderName = Constants.FILE_FOLDER_FILE+Constants.FILE_FOLDER_AVATAR_NAME;//头像目录名
                String avatarFilePath = appConfig.getProjectFolder()+avatarFolderName+fileId+Constants.IMAGE_SUFFIX;//头像文件路径
                if(showCover){
                    avatarFilePath += Constants.COVER_IMAGE_SUFFIX;//显示封面
                }
                file = new File(avatarFilePath);
                if(!file.exists()){
                   throw new BusinessException(ResponseCodeEnum.CODE_602);
                }
            }else{
                file = chatMessageService.downloadFile(tokenUserInfoDto, Long.parseLong(fileId), showCover);
            }

            //设置响应头
            response.setContentType("application/x-msdownload;charset=UTF-8");//表示是下载流
            response.setHeader("Content-Disposition", "attachment;filename="+file.getName());
            response.setContentLengthLong(file.length());

            inputStream = new FileInputStream(file);//创建输入流---读取文件,file是本地文件对象
            byte[] byteData = new byte[1024];//创建缓冲区---用于读写数据
            outputStream = response.getOutputStream();//获取HTTP输出流---通过HTTP协议发送给客户端
            int len;
            while ((len = inputStream.read(byteData))!=-1){
                outputStream.write(byteData, 0, len);
            }
            outputStream.flush();//刷新缓冲区,进行输出
        }catch (Exception e){
            throw new BusinessException("下载文件失败");
        }finally {
            //在流里面，后创建的流先关闭
            if(outputStream != null){
                try {
                    outputStream.close();
                }catch (Exception e) {
                    log.error("关闭流异常", e);
                }
            }
            if(inputStream != null){
                try {
                    inputStream.close();
                } catch (Exception e) {
                    log.error("关闭流异常", e);
                }
            }

        }
    }

//    /**
//     * 撤回消息
//     */
//    @RequestMapping("/withdrawMessage")
//    @GlobalInterceptor
//    public ResponseVO withdrawMessage(HttpServletRequest request,
//                                      @NotNull Long messageId) {
//        TokenUserInfoDto tokenUserInfoDto = getTokenUserInfo(request);
//        MessageSendDto messageSendDto = chatMessageService.withdrawMessage(messageId, tokenUserInfoDto);
//        return getSuccessResponseVO(messageSendDto);
//    }

}
